package info.xmlprint.core.project;

import info.xmlprint.core.format.FormatGroup;
import info.xmlprint.core.innerlink.InnerLinkGroup;
import info.xmlprint.core.mapping.MappingGroup;
import info.xmlprint.core.referencesystem.PageMasterGroup;
import info.xmlprint.core.referencesystem.ReferenceFieldGroup;
import info.xmlprint.core.referencesystem.ReferencingSystemGroup;
import info.xmlprint.core.xml.PElementGroup;
import info.xmlprint.core.xml.XMLScanner;
import info.xmlprint.run.RuntimeUtil;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IProject;

public class PrintProject {
	private static Logger logger = Logger.getLogger(PrintProject.class
			.getName());

	private MappingGroup mappingGroup;
	private FormatGroup formatGroup;
	private ReferencingSystemGroup referencingSystemGroup;
	private ReferenceFieldGroup referenceFieldGroup;
	private PageMasterGroup pageMasterGroup;
	private IProject project;
	private InnerLinkGroup innerLinkGroup;

	private boolean readMappingGroupXml = false;

	private PrintProject() {
	}

	public PrintProject(IProject project) {
		this.project = project;
	}

	public PrintProject getClone() {
		IProject project = getProject();
		PrintProject clone = new PrintProject();

		if (project == null) {
			logger.error("error: null IProject");
			return null;
		}

		FormatGroup fg = getFormatGroup();
		if (fg == null) {
			logger.error("error: null formatGroup");
			return null;
		}

		MappingGroup mg = getMappingGroup();
		if (mg == null) {
			logger.error("error: null mappingGroup");
			return null;
		}

		ReferencingSystemGroup rsg = getReferencingSystemGroup();
		if (rsg == null) {
			logger.error("error: null referencingSystemGroup");
			return null;
		}
		ReferenceFieldGroup rfg = getReferenceFieldGroup();
		if (rfg == null) {
			logger.error("error: null referenceFieldGroup");
			return null;
		}
		
		PageMasterGroup pmg = getPageMasterGroup();
		if (pmg == null) {
			logger.error("error: null pageMastergroup");
			return null;
		}
		

		InnerLinkGroup ilg = getInnerLinkGroup();
		if (ilg == null) {
			logger.error("error: null innerLinkGroup");
			return null;
		}

		FormatGroup newFg = fg.objClone();
		MappingGroup newMg = mg.objClone();
		newMg.setFormatGroup(newFg);
		clone.setProject(project);
		clone.setFormatGroup(newFg);
		clone.setMappingGroup(newMg);
		clone.setReferenceFieldGroup(rfg.objClone());
		clone.setReferencingSystemGroup(rsg.objClone());
		clone.setPageMasterGroup(pmg.objClone());
		clone.setInnerLinkGroup(ilg.objClone());
		return clone;

	}

	public FormatGroup getFormatGroup() {
		if (formatGroup == null) {
			RuntimeUtil rt = RuntimeUtil.getInstance();
			testIfLoad();

			if (formatGroup == null) {
				formatGroup = rt.getDefaultFormatGroup();
				if (mappingGroup != null) {
					mappingGroup.setFormatGroup(formatGroup);
				}
			}
		}

		return formatGroup;
	}

	public InnerLinkGroup getInnerLinkGroup() {
		if (innerLinkGroup == null) {
			testIfLoad();

			if (innerLinkGroup == null) {
				innerLinkGroup = new InnerLinkGroup();
			}
		}

		return innerLinkGroup;

	}

	public MappingGroup getMappingGroup() {
		if (mappingGroup == null) {
			testIfLoad();
			if (mappingGroup == null) {
				mappingGroup = new MappingGroup();
				mappingGroup.setFormatGroup(formatGroup);
			}
		}
		return mappingGroup;
	}

	public PElementGroup getPElementGroup() {
		return RuntimeUtil.getInstance().getPElementGroup(this);
	}

	public IProject getProject() {
		return project;
	}

	public ReferenceFieldGroup getReferenceFieldGroup() {
		if (referenceFieldGroup == null) {
			testIfLoad();
			if (referenceFieldGroup == null) {
				referenceFieldGroup = new ReferenceFieldGroup();
			}
		}
		return referenceFieldGroup;
	}

	public ReferencingSystemGroup getReferencingSystemGroup() {
		if (referencingSystemGroup == null) {
			testIfLoad();
			if (referencingSystemGroup == null) {
				referencingSystemGroup = new ReferencingSystemGroup();
			}
		}
		return referencingSystemGroup;
	}
	
	public PageMasterGroup getPageMasterGroup() {
		if (pageMasterGroup == null) {
			testIfLoad();
			if (pageMasterGroup == null) {
				pageMasterGroup = RuntimeUtil.getInstance().getDefaultPageMasterGroup();
			}
		} else if (pageMasterGroup.getItemCount() == 0) // for existing projects
			pageMasterGroup = RuntimeUtil.getInstance().getDefaultPageMasterGroup();
		return pageMasterGroup;
	}

	public XMLScanner getXMLScanner(boolean reRead) {
		if (reRead) {
			return RuntimeUtil.getInstance().getDefaultXMLScanner(this);
		}
		return RuntimeUtil.getInstance().getDefaultXMLScanner(this);
	}

	public void setFormatGroup(FormatGroup formatGroup) {
		this.formatGroup = formatGroup;
	}

	public void setInnerLinkGroup(InnerLinkGroup innerLinkGroup) {
		this.innerLinkGroup = innerLinkGroup;
	}

	public void setMappingGroup(MappingGroup mappingGroup) {
		this.mappingGroup = mappingGroup;
	}

	public void setProject(IProject project) {
		this.project = project;
	}

	public void setReferenceFieldGroup(ReferenceFieldGroup referenceFieldGroup) {
		this.referenceFieldGroup = referenceFieldGroup;
	}

	public void setReferencingSystemGroup(
			ReferencingSystemGroup referencingSystemGroup) {
		this.referencingSystemGroup = referencingSystemGroup;
	}
	
	public void setPageMasterGroup(
			PageMasterGroup pageMasterGroup) {
		this.pageMasterGroup = pageMasterGroup;
	}
	

	private void testIfLoad() {
		if (!readMappingGroupXml
				&& RuntimeUtil.getInstance().readSettingXml(this)) {
			readMappingGroupXml = true;
		}
	}

	public boolean updateWith(PrintProject pProject) {
		if (pProject == null) {
			return false;
		}
		setProject(pProject.getProject());
		setFormatGroup(pProject.getFormatGroup());
		setMappingGroup(pProject.getMappingGroup());
		setReferenceFieldGroup(pProject.getReferenceFieldGroup());
		setReferencingSystemGroup(pProject.getReferencingSystemGroup());
		setPageMasterGroup(pProject.getPageMasterGroup());
		setInnerLinkGroup(pProject.getInnerLinkGroup());
		return true;
	}
}
